package com.idbk.chargestation;

import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Message;
import android.support.multidex.MultiDexApplication;
import android.util.Log;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.idbk.chargestation.api.APIForUser;
import com.idbk.chargestation.api.ChargeStationURL;
import com.idbk.chargestation.app.ConfigSharedPreferences;
import com.idbk.chargestation.app.ManagerLogin;
import com.idbk.chargestation.bean.JsonBase;
import com.idbk.chargestation.bean.JsonMyMessage;
import com.idbk.chargestation.db.MessageDatabase;
import com.idbk.chargestation.util.Des;
import com.idbk.chargestation.util.GlobalResult;
import com.idbk.chargestation.util.GsonUtils;
import com.idbk.chargestation.util.NotificationUtil;
import com.idbk.chargestation.wrapper.okhttp.MyInterceptor;
import com.idbk.chargestation.wrapper.okhttp.OkHttp3DownLoader;
import com.squareup.picasso.Picasso;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.Callback;
import com.zhy.http.okhttp.https.HttpsUtils;
import com.zhy.http.okhttp.log.LoggerInterceptor;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Response;

/**
 * 全局应用程序类：用于保存和调用全局应用配置及访问网络数据
 *
 * @author lupc, zhx
 */
public class AppContext extends MultiDexApplication {

    public static final String TAG = AppContext.class.getSimpleName();
    private static AppContext instance;
    //是否登录
    private boolean isLogin;
    //登录凭证
    private String token;
    /**
     * token有效时间，单位：分钟
     */
    private int expires;
    /**
     * 登录时间(实际上是token的更新时间，每次请求都会重置该时间)
     */
    private Date loginDatetime;
    /**
     * 用户Id
     */
    private int mUserId = -1;
    private String mUserNickName = "";
    private static MyAppHandler mHandler;
    /**
     * 个推的cid
     */
    private String pushClientId = null;
    /**
     * 是否有未读消息
     */
    private boolean hasUnreadMessage = false;
    /**
     * 是否已提交车主认证信息
     */
    public int isSubmitted;
    /**
     * 用户类型，1:表示普通用户；2：表示企业号用户
     */
    public int userRole = 1;
    //用户定位 经度
    private double lng = 113.905971;
    //用户定位 纬度
    private double lat = 22.969091;
    private int mMaxRegisterNumber;
    private RequestQueue mVolleyRequestQueue;
    private final static String KEY = "EANAzDr0eLDVwiv5dBM535xpsPQ8Ny6-";
    /**
     * 第三方app和微信通信的openapi接口
     */
    private IWXAPI wxAPI;

    @Override
    public void onCreate() {
        super.onCreate();

        instance = this;

        init();

        if (mHandler == null) {
            mHandler = new MyAppHandler();
        }
    }

    private void init() {
        //初始化基本参数
        this.isLogin = false;
        mMaxRegisterNumber = 5;
        //bugly
//        CrashReport.initCrashReport(getApplicationContext());
//        CrashReport.testJavaCrash();
        //初始化volley框架
        initVolley();
        //初始化okhttp框架
        initOKHttp();
        //初始化图片加载器--这个必须放在okhttp后面
        initPicasso();
        //初始化微信代码
        initWX();

        //初始化经纬度;
        lng = 113;
        lat = 22;
    }

    private void initVolley() {
        //暂时不需要用https
        //mVolleyRequestQueue = Volley.newRequestQueue(this, new HurlStack(null, VolleyHttps.getSSLSocketFactory_Certificate(this, null, R.raw.ca)));
        mVolleyRequestQueue = Volley.newRequestQueue(this);
        mVolleyRequestQueue.start();
    }

    private void initOKHttp() {
        //初始化okhttp框架
        HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(new InputStream[]{getResources().openRawResource(R.raw.ca)}, null, null);
        // 初始化网络请求
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                //配置日志
                .addInterceptor(new LoggerInterceptor("OKHTTP"))
                //配置HTTPS访问
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .connectTimeout(10000L, TimeUnit.MILLISECONDS)
                .readTimeout(30000L, TimeUnit.MILLISECONDS)
//                .hostnameVerifier(new HostnameVerifier() {
//
//                    @Override
//                    public boolean verify(String hostname, SSLSession session) {
//                        System.out.println("hostname   ->" + hostname);
//                        if ("192.168.162.26".equals(hostname)
//                                || "api.eastevs.com".equals(hostname)) {
//                            return true;
//
//                        } else {
//                            HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
//                            return hv.verify(hostname, session);
//                        }
//                    }
//                })
                .build();
        //
        OkHttpUtils.initClient(okHttpClient);
    }

    /**
     * 初始化 图片加载器
     */
    private void initPicasso() {
        OkHttpClient client = new OkHttpClient
                .Builder()
                .addNetworkInterceptor(new MyInterceptor())
                .cache(new Cache(getExternalCacheDir(), 1024 * 1024 * 100))
                .build();

        Picasso picasso = new Picasso.Builder(this)
                .downloader(new OkHttp3DownLoader(client))
                .build();
        if (BuildConfig.DEBUG) {
            picasso.setIndicatorsEnabled(true);
        }
        Picasso.setSingletonInstance(picasso);
    }

    public IWXAPI getWxApi() {
        return wxAPI;
    }

    private void initWX() {
        final String appId = getResources().getString(R.string.weixin_app_id);
        wxAPI = WXAPIFactory.createWXAPI(this, null);
        // 将该app注册到微信
        wxAPI.registerApp(appId);
    }

    public RequestQueue getVolleyQueue() {
        return mVolleyRequestQueue;
    }

    public static AppContext getInstance() {
        return instance;
    }

    public static void sendMessage(Message msg) {
        mHandler.sendMessage(msg);
    }

    private static class MyAppHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0://接收透传消息
                    String jsg = (String) msg.obj;
                    AppContext.getInstance().showNotifyMsg(jsg);
                    break;
                case 1://接收cid
                    String cid = (String) msg.obj;
                    AppContext.getInstance().setPushClientId(cid);
                    break;
                default:
                    break;
            }
        }
    }

    private void showNotifyMsg(String msg) {
        if (isLogin()) {
            MessageDatabase messageDB = new MessageDatabase(this);
            JsonMyMessage item = new JsonMyMessage(getLoginUserName(), msg);
            messageDB.insertMessage(item);
            messageDB.close();
            NotificationUtil.showString(this, msg);
        }
    }

    public boolean isLogin() {
        return isLogin && !isLoginExpired();
    }

    public String getToken() {
        return token;
    }

    public double getLng() {
        return lng;
    }

    public double getLat() {
        return lat;
    }

    public void setLocation(double lat, double lng) {
        this.lat = lat;
        this.lng = lng;
    }

    public void saveUserInfo(String token, String loginUser, String loginPassword, int expires) {
        this.token = token;
        this.isLogin = true;
        this.loginDatetime = new Date();
        this.expires = expires;
        //将用户信息保存到preference当中
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        sp.edit()
                .putString("loginUser", loginUser)
                .putString("loginPassword", loginPassword)
                .apply();
        //将推送CID报告给服务器
        bindGetUiCID();
    }

    public boolean isLoginExpired() {
        if (expires == 0) {
            return true;
        }
        long t = System.currentTimeMillis() - loginDatetime.getTime();
        long mt = t / 1000 / 60;
        return mt > expires;
    }

    public void saveUserInfo(String token, String loginUser, String loginPassword, int expires, int userRole) {
        this.token = token;
        this.isLogin = true;
        this.loginDatetime = new Date();
        this.expires = expires;
        this.userRole = userRole;
        //将用户信息保存到preference当中
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        sp.edit()
                .putString("loginUser", loginUser)
                .putString("loginPassword", loginPassword)
                .apply();
        //将推送CID报告给服务器
        bindGetUiCID();
    }

    public int getUserRole() {
        return userRole;
    }

//    public boolean isGetCode() {
//        int registerNumber;
//        String mRegisterTime;
//        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
//        if ("".equals(sp.getString(ManagerLogin.KEY_USER_REGISTER_DATE, ""))) {
//            sp.edit()
//                    .putString(ManagerLogin.KEY_USER_REGISTER_DATE, dateToString(new Date()))
//                    .putInt(ManagerLogin.KEY_USER_REGISTER_NUMBER, 0)
//                    .apply();
//
//            mRegisterTime = dateToString(new Date());
//            registerNumber = 0;
//
//        } else {
//            mRegisterTime = sp.getString(ManagerLogin.KEY_USER_REGISTER_DATE, "");
//            registerNumber = sp.getInt(ManagerLogin.KEY_USER_REGISTER_NUMBER, 0);
//        }
//
//        String currentTime = dateToString(new Date());
//        if (currentTime.equals(mRegisterTime)) {
//            if (registerNumber < mMaxRegisterNumber) {
//                registerNumber++;
//                return sp.edit()
//                        .putInt(ManagerLogin.KEY_USER_REGISTER_NUMBER, registerNumber)
//                        .commit();
//
//            } else {
//                return false;
//            }
//        } else {
//            return sp.edit()
//                    .putString(ManagerLogin.KEY_USER_REGISTER_DATE, currentTime)
//                    .putInt(ManagerLogin.KEY_USER_REGISTER_NUMBER, 1)
//                    .commit();
//        }
//    }

    private String dateToString(Date date) {
        return new SimpleDateFormat("yyyyMMdd", Locale.CHINA).format(date);
    }

    public String getLoginUserName() {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        return sp.getString(ManagerLogin.KEY_LOGIN_NAME, "");
    }

    public String getLoginPassword() {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        return sp.getString(ManagerLogin.KEY_LOGIN_PASSWORD, "");
    }

    public void setLoginPassword(String loginPassword) {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        sp.edit().putString(ManagerLogin.KEY_LOGIN_PASSWORD, loginPassword).apply();
    }

    public String getUserPhoneNumber() {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        return sp.getString(ManagerLogin.KEY_LOGIN_NAME, "");
    }

    public void setUserInfo(int userId, String nickName) {
        mUserId = userId;
        mUserNickName = nickName;
    }

    public String getUserNickName() {
        return mUserNickName;
    }

    public int getMyUserId() {
        return mUserId;
    }

    /**
     * 获取当前城市名称
     *
     * @return 前城市名称
     */
    public String getCurrentCityName() {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        return sp.getString(ConfigSharedPreferences.KEY_CITY, ConfigSharedPreferences.DEFAULT_CITY);
    }

    /**
     * 设置当前城市名称
     *
     * @param city 当前城市名称
     */
    public void setCurrentCityName(String city) {
        if (city == null || "".equals(city)) {
            return;
        }
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        sp.edit().putString(ConfigSharedPreferences.KEY_CITY, city).apply();
    }

    /**
     * 登出，会清理掉密码
     */
    public void logout() {
        clearLoginState();
        //
        if (userRole == 1) {
            SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
            sp.edit().remove(ManagerLogin.KEY_LOGIN_PASSWORD).apply();
        }else if (userRole == 2){
            SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
            sp.edit().remove(ManagerLogin.KEY_LOGIN_PASSWORD).apply();
            sp.edit().remove(ManagerLogin.KEY_LOGIN_NAME).apply();
        }
    }

    /**
     * 清理 登录状态
     */
    public void clearLoginState() {
        isLogin = false;
        token = null;
        expires = 0;

        mUserId = -1;
        mUserNickName = "";
        //unbindGetuiCid();
    }

    public String getPushClientId() {
        return pushClientId;
    }

    public void setPushClientId(String pushClientId) {
        //记录CID
        this.pushClientId = pushClientId;

        bindGetUiCID();
    }

    private void bindGetUiCID() {
        if (isLogin && pushClientId != null && token != null) {
            Log.d(TAG, "cid:" + pushClientId + "\ntoken:" + token);
            //上传cid
            APIForUser.registerGetUiCID(pushClientId, new Callback<String>() {

                @Override
                public String parseNetworkResponse(Response response, int id) throws Exception {
                    return response.body().string();
                }

                @Override
                public void onError(Call call, Exception e, int id) {
                    Log.e(TAG, "上传CID失败");
                    Log.e(TAG, e.getMessage());
                }

                @Override
                public void onResponse(String response, int id) {
                    JsonBase result = GsonUtils.toBean(JsonBase.class, response);
                    if (result != null && result.status == GlobalResult.OK.getStatus()) {
                        Log.i(TAG, "上传CID成功");
                    } else {
                        Log.i(TAG, "上传CID失败");
                    }
                }
            });
            //绑定别名
            //PushManager.getInstance().bindAlias(this, getLoginUserName());
        }
    }

    public String getSign(String mobile, String timestamp) throws Exception {
        String param = "mobile=" + mobile + "&timeStamp=" + timestamp;//请求参数以及排序
        return Des.encrypt(Des.MD5Encrypt(param.getBytes("UTF-8")), KEY);
    }

    public int getApplicationVersionCode() {
        int versionCode = 0;
        try {
            PackageManager manager = getPackageManager();
            PackageInfo info = manager.getPackageInfo(getPackageName(), 0);
            versionCode = info.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    public void saveVersionCode(int code) {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        sp.edit().putInt("application_version_code", code)
                .apply();
    }

    public int getSaveVersionCode() {
        SharedPreferences sp = getSharedPreferences(ConfigSharedPreferences.CHARGE_STATION, MODE_PRIVATE);
        return sp.getInt("application_version_code", -1);
    }

//    private void unbindGetuiCid(){
//        PushManager.getInstance().unBindAlias(this, getLoginUserName(), true);
//    }

    public boolean isHasUnreadMessage() {
        return hasUnreadMessage;
    }

    public void setHasUnreadMessage(boolean hasUnreadMessage) {
        this.hasUnreadMessage = hasUnreadMessage;
    }

    public int getWorkNetMode() {
        return ChargeStationURL.workNetMode;
    }

    public void setWorkNetMode(int mode) {
        logout();
        ChargeStationURL.workNetMode = mode;
    }

    public void setCertification(int isSubmitted) {
        this.isSubmitted = isSubmitted;
    }

}
